package com.creative.xcx.service.Impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import com.creative.user.service.UserInfoService;
import com.creative.xcx.domain.Material;
import com.creative.xcx.domain.UserFavorite;
import com.creative.xcx.domain.vo.UserFavoriteVo;
import com.creative.xcx.mapper.UserFavoriteMapper;
import com.creative.xcx.service.MaterialService;
import com.creative.xcx.service.UserFavoriteService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import static com.creative.xcx.domain.constant.common.CACHE_FAVORITE_KEY;

/**
 * @author ling
 * @description 用户收藏
 * @date 2025-03-23
 */
@Service
public class UserFavoriteServiceImpl implements UserFavoriteService {

    @Resource
    private UserFavoriteMapper userFavoriteMapper;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private MaterialService materialService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Integer insert(UserFavorite userFavorite) {

        userFavorite.setCreateTime(DateUtil.date());
//        获取对应素材信息
        Material materialInfo = materialService.selectById(userFavorite.getMaterialId());
        materialInfo.setCollectionCount(materialInfo.getCollectionCount() + 1);
//        修改素材表中的收藏数
        materialService.collectMaterial(materialInfo);
//        在redis中添加用户的收藏数

        long timestamp = System.currentTimeMillis();
        // 更新优化的收藏列表缓存
        String key = CACHE_FAVORITE_KEY + StpUtil.getLoginId();
        stringRedisTemplate.opsForZSet().add(key, userFavorite.getMaterialId(), timestamp);
        return userFavoriteMapper.insert(userFavorite);
    }

    @Override
    public Integer delete(UserFavorite userFavorite) {
        // 参数校验
        if (userFavorite == null) {
            return 0;
        }
        // 校验是否存在
        if (userFavoriteMapper.selectByUserIdAndMaterialId(userFavorite) == null) {
            return 0;
        }
        //        获取对应素材信息
        Material materialInfo = materialService.selectById(userFavorite.getMaterialId());
        // 防止收藏数为负数
        if (materialInfo.getCollectionCount() > 0) {
            materialInfo.setCollectionCount(materialInfo.getCollectionCount() - 1);
            // 更新素材表的收藏数
            materialService.unCollectMaterial(materialInfo);
        }
        //  删除Redis缓存
        String key = CACHE_FAVORITE_KEY + StpUtil.getLoginId();
        stringRedisTemplate.opsForZSet().remove(key, userFavorite.getMaterialId());

        return userFavoriteMapper.delete(userFavorite);
    }


    @Override
    public Integer deleteBatch(Long[] ids) {
        return userFavoriteMapper.deleteBatch(ids);
    }


    @Override
    public Integer update(UserFavorite userFavorite) {

        return userFavoriteMapper.update(userFavorite);
    }

    @Override
    public UserFavorite selectById(Long id) {
        return userFavoriteMapper.selectById(id);
    }

    @Override
    public List<UserFavoriteVo> selectUserFavoriteList(UserFavorite userFavorite) {
//        查看缓存是否存在
        String key = CACHE_FAVORITE_KEY + userFavorite.getUserId();
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))) {
            // 计算分页游标
            long start = ((userFavorite.getPageNum() - 1L) * userFavorite.getPageSize());
            long end = start + userFavorite.getPageSize() - 1;
            // 从Redis获取分页素材ID
            Set<String> materialIds = stringRedisTemplate.opsForZSet()
                    .reverseRange(key, start, end);
//            遍历分页素材ID
            System.out.println("查询列表：");
            for (String materialId : materialIds) {
                System.out.println(materialId);
            }
            if (materialIds == null || materialIds.isEmpty()) {
                return Collections.emptyList();
            }
//            将set集合转为list
            List<String> materialIdList = materialIds.stream().toList();
            // 批量查询素材详情
            return userFavoriteMapper.batchGetMaterials(userFavorite.getUserId(), materialIdList);
        } else {
            //     不存在缓存，则添加缓存
            insertCache(StpUtil.getLoginId().toString());
            //获取当前用户的收藏列表
            PageHelper.startPage(userFavorite.getPageNum(), userFavorite.getPageSize());
            List<UserFavoriteVo> list = userFavoriteMapper.selectUserFavoriteList(userFavorite);
            Page<UserFavoriteVo> page = (Page<UserFavoriteVo>) list;

            return page.getResult();
        }
    }

    @Override
    public List<UserFavorite> exportBatch(Long[] ids) {
        return userFavoriteMapper.exportBatch(ids);
    }

    // 数据库加载缓存(全部添加)
    private void insertCache(String userId) {
        List<UserFavorite> dbData = userFavoriteMapper.selectByUserId(userId);
        if (!dbData.isEmpty()) {
//           遍历数据，将数据添加到Redis中
            for (UserFavorite favorite : dbData) {
                stringRedisTemplate.opsForZSet().add(CACHE_FAVORITE_KEY + userId, favorite.getMaterialId(), favorite.getCreateTime().getTime());
            }
        }
    }
}
